import {useLoginUser} from "../hooks/LoginHooks.tsx";
import TextArea, {TextAreaProps} from "antd/es/input/TextArea";
import {Button, Divider, message, Pagination, Spin} from "antd";
import {
  CommentInfo,
  CommentPageParam,
  CommentParam,
  PageInfo,
  SubCommentCache,
  SubCommentInfo
} from "../types/commonTypes.ts";
import {doDeleteComment, doGetCommentPage, doPraiseComment, doSubmitComment} from "../api/apis.ts";
import {useEffect, useRef, useState} from "react";
import {useClickAway} from 'ahooks';
import CommentItem from "./CommentItem.tsx";
import * as React from "react";

type CommentProps = {
  commentPage: PageInfo<CommentInfo>,
  onChangePage: (page: number, size: number) => void,
  getCommentPage: (pageParam: CommentPageParam) => void,
  onChangeTotalCommentCount: (total?: string) => void,
  qid: string,
  creator: string,
}
export default function ({
                           commentPage,
                           onChangePage,
                           qid,
                           getCommentPage,
                           onChangeTotalCommentCount,
                           creator
                         }: CommentProps) {
  useEffect(() => {
    setCommentList(commentPage.records)
  }, [commentPage]);
  const [subCommentCache, setSubCommentCache] = useState<SubCommentCache>({})
  const [commentList, setCommentList] = useState(commentPage.records)
  const user = useLoginUser();
  const [showMainConfirm, setShowMainConfirm] = useState(false)
  const [mainInput, setMainInput] = useState('');//把vaule的值存起来，方便其他地方用;
  const [mainInputAttr, setMainInputAttr] = useState<TextAreaProps>({
    placeholder: '请输入评论内容',
    status: ''
  })
  const focusEl = useRef<HTMLDivElement>(null);
  const getSubCommentPage = async (pageParam: CommentPageParam, showTip = false) => {
    const {code, data} = await doGetCommentPage(qid, pageParam);
    if (code == 200) {
      setSubCommentCache(pre => {
        const newInfo = {...pre[pageParam.pid || '']}
        newInfo.subComments = data;
        newInfo.queryStatus = 'success';
        return {...pre, [pageParam.pid || '']: newInfo}
      });
      onChangeTotalCommentCount(data.totalComments);
      if (showTip && data.total === "0") {
        message.warning('请先登录后再评论');
      }
    } else {
      setSubCommentCache(pre => {
        const newInfo = {...pre[pageParam.pid || '']}
        newInfo.queryStatus = 'fail';
        return {...pre, [pageParam.pid || '']: newInfo}
      })
    }
  }
  useClickAway(() => {
    setShowMainConfirm(false)
  }, focusEl);
  const submitComment = async (type: number, content?: string, parentId?: string) => {
    const param: CommentParam = {
      type,
      content,
      parentId: parentId || qid,
    }
    const {code, msg} = await doSubmitComment(qid, param)
    if (code == 200) {
      message.success('评论成功');
      getCommentPage({current: 1, size: commentPage?.size || 5, type: 1})
      setMainInput('')
      setShowMainConfirm(false)
    } else {
      message.error(msg);
    }
  }
  const submitCommentOnComment = async (pid: string, content?: string, size?: number, state?: string) => {
    if (state === 'loading') {
      return;
    }
    if (content) {
      const {code, msg} = await doSubmitComment(qid, {
        type: 2,
        content,
        parentId: pid,
      });
      if (code == 200) {
        message.success('评论成功');
        getSubCommentPage({current: 1, size: size || 5, type: 2, pid: pid});
        setSubCommentCache(pre => ({
          ...pre, [pid]: {...pre[pid], lastComment: ''}
        }));
      } else {
        message.error(msg);
      }
    } else {
      message.warning('评论内容不能为空');
    }
  }
  const onMainInputChange = (value: any) => {
    setMainInput(value.target.value)
    if (value.target.value.length > 0) {
      setMainInputAttr(pre => ({...pre, status: ''}))
    }
  }

  function mapPraiseStatus(commentId: string, targetStatus: number) {
    return (cm: CommentInfo) => {
      if (cm.id === commentId) {
        cm.likedStatus = targetStatus;
        cm.likeCount = String(targetStatus === 0 ?
          Math.max((Number(cm.likeCount) - 1), 0) :
          Number(cm.likeCount) + 1)
      }
      return cm;
    };
  }

  const onPraiseComment = async (commentId?: string, likedStatus?: number, fromSub = false, pid = '') => {
    if (commentId) {
      const targetStatus = likedStatus === 0 ? 1 : 0;
      // 点赞评论
      const {code, msg} = await doPraiseComment(commentId, targetStatus);
      if (code === 200) {
        if (fromSub) {
          setSubCommentCache(prevState => {
            const current = {...prevState[pid]};
            if (current.subComments.records?.length) {
              current.subComments.records = current.subComments.records.map(mapPraiseStatus(commentId, targetStatus))
            }
            return {...prevState, [pid]: current}
          })
          return;
        }
        setCommentList((preList) => {
          return preList?.map(mapPraiseStatus(commentId, targetStatus))
        })
      } else {
        message.error(msg);
      }

    }
  }
  const changeSubCommentStatus = (pid: string) => {
    const current = subCommentCache[pid];
    if (current) {
      const nextStatus = {...current};
      nextStatus.expanded = !current.expanded;
      if (current.queryStatus === 'fail') {
        current.queryStatus = 'loading';
        getSubCommentPage({
          pid,
          current: current.subComments?.current || 1,
          size: current.subComments?.size || 5
        }, true)
      }
      if (!user && nextStatus.subComments.total == '0') {
        message.warning('请先登录后再评论');
      }
      setSubCommentCache(pre => ({...pre, [pid]: nextStatus}))
    } else {
      // 查询评论
      const current: SubCommentInfo = {
        expanded: true,
        queryStatus: 'loading',
        subComments: {
          current: 1,
          size: 5,
          records: []
        }
      }
      setSubCommentCache(pre => ({...pre, [pid]: current}))
      getSubCommentPage({
        pid, current: current.subComments.current, size: current.subComments.size, type: 2
      }, !user)
    }
  }
  const onChangeSubPage = async (page: number, size: number, pid: string) => {
    const {code, data} = await doGetCommentPage(qid,
      {current: page, size: size, type: 2, pid}
    )
    if (code == 200) {
      onChangeTotalCommentCount(data.totalComments);
      setSubCommentCache(pre => {
        const current = {...pre[pid]};
        // debugger
        current.subComments = data;
        current.lastComment = '';
        return {...pre, [pid]: current}
      });
    }
  }
  const deleteComment = async (cid: string, type: number, pid?: string) => {
    const {code, msg} = await doDeleteComment(cid)
    if (code == 200) {
      if (type == 1) {
        getCommentPage({current: 1, size: commentPage?.size || 5, type: 1})
      } else if (type == 2 && pid) {
        const size = subCommentCache[pid].subComments.size
        getSubCommentPage({current: 1, size: size || 5, type: 2, pid: pid});
      }
      message.success('删除成功')
    } else {
      message.error(msg)
    }
  }
  const onEnterDown = (e: React.KeyboardEvent<any>, callback: Function) => {
    const {code, shiftKey} = e;
    if (code === 'Enter' && !shiftKey) {
      callback();
      e.preventDefault();
    }
  }

  function onSubmitPrimaryComment() {
    if (mainInput.length > 0) {
      submitComment(1, mainInput);
      return;
    }
    setMainInputAttr(pre => ({...pre, status: 'error'}))
  }

  return <>
    {user || commentList?.length ?
      <>
        <div className={'comment-container'}>
          <div ref={focusEl}>
            {user ? <div>
              <div className='comment-box'>
                <img className='author-header' src={user?.avatarUrl} alt=""/>
                <TextArea onFocus={() => setShowMainConfirm(true)}
                          onChange={onMainInputChange}
                          value={mainInput}
                          onKeyDown={(e) => onEnterDown(e, () => onSubmitPrimaryComment())}
                          status={mainInputAttr.status}
                          placeholder={mainInputAttr.placeholder} autoSize/>
              </div>
              {
                showMainConfirm ? <div className={'publish-btn '}>
                  <Button type="primary" onClick={() => {
                    onSubmitPrimaryComment();
                  }}>发布</Button>
                </div> : ''
              }
              <Divider/>
            </div> : ''}
          </div>
          {commentList?.map(record => <div key={record.id}>
            <div className='comment-item'>
              <CommentItem changeSubCommentStatus={changeSubCommentStatus}
                           onPraiseComment={onPraiseComment}
                           creator={creator}
                           onDeleteComment={(cid) => deleteComment(cid, 1)}
                           record={record}/>
            </div>
            {
              subCommentCache[record.id]?.expanded && (user || subCommentCache[record.id].subComments.records?.length) ?
                <div className='subcomment-container'>
                  {user ? <div className='comment-box comment-box-sub'>
                    <TextArea id={'subComment-' + record.id}
                              value={subCommentCache[record.id].lastComment}
                              onKeyDown={(e) => {
                                onEnterDown(e, () => submitCommentOnComment(record.id,
                                  subCommentCache[record.id].lastComment,
                                  subCommentCache[record.id].subComments.size,
                                  subCommentCache[record.id].queryStatus,
                                ))
                              }}
                              onChange={(e) => {
                                setSubCommentCache(pre =>
                                  ({
                                    ...pre, [record.id]: {...pre[record.id], lastComment: e.target.value}
                                  }))
                              }}
                              placeholder='请输入评论内容' autoSize/>
                    <Button
                      onClick={() => submitCommentOnComment(record.id,
                        subCommentCache[record.id].lastComment,
                        subCommentCache[record.id].subComments.size,
                        subCommentCache[record.id].queryStatus,
                      )}
                      style={{marginLeft: '5px'}}
                      type='primary'>回复</Button>
                  </div> : ''}
                  {
                    subCommentCache[record.id].queryStatus === 'loading' ?
                      <div className='spin-container'>
                        <Spin/>
                      </div> :
                      <div>
                        {
                          subCommentCache[record.id].subComments.records?.map(item => (
                            <div key={item.id}>
                              <CommentItem record={item}
                                           creator={creator}
                                           onDeleteComment={(id) => deleteComment(id, 2, record.id)}
                                           onPraiseComment={(id, status) => onPraiseComment(id, status, true, record.id)}/>
                            </div>))
                        }
                        {
                          Number(subCommentCache[record.id].subComments?.total) >= 5 ?
                            <div className={'comment-pagination'}>
                              <Pagination current={subCommentCache[record.id].subComments?.current}
                                          showSizeChanger
                                          showQuickJumper
                                          pageSizeOptions={['5', '10', '20']}
                                          total={subCommentCache[record.id].subComments?.total}
                                          pageSize={subCommentCache[record.id].subComments?.size}
                                          onChange={(page, size) => onChangeSubPage(page, size, record.id)}/>
                            </div> : ''
                        }
                      </div>
                  }
                </div> : ''
            }
          </div>)}
          {
            Number(commentPage?.total) >= 5 ?
              <div className={'comment-pagination'}>
                <Pagination current={commentPage?.current}
                            showSizeChanger
                            showQuickJumper
                            pageSizeOptions={['5', '10', '20']}
                            total={commentPage?.total}
                            pageSize={commentPage?.size}
                            onChange={onChangePage}/>
              </div> : ''
          }
        </div>
      </> : <></>}
  </>
}